package me.xADudex.RandomLocation;

import com.massivecraft.factions.Factions;
import com.palmergames.bukkit.towny.Towny;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.wimbli.WorldBorder.WorldBorder;
import me.ryanhamshire.GriefPrevention.GriefPrevention;
import net.milkbowl.vault.economy.Economy;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.event.Listener;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.RegisteredServiceProvider;
import org.bukkit.plugin.java.JavaPlugin;

import java.io.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Main extends JavaPlugin
{
    Timer timer;
    ZoneManager zoneManager;
    CmdHandler cmdHandler;
    Events events;
    PortalManager portalManager;
    Economy econ;
    String updateMsg;
    final String[] oldConfigs;
    FileConfiguration defaultConfig;
    boolean townyHook;
    boolean factionHook;
    boolean worldBorderHook;
    boolean worldBorderInstalled;
    boolean griefPreventionHook;
    boolean vaultHook;
    boolean worldGuardHook;
    private boolean disabling;
    List<String> ignoreFactions;
    List<String> ignoreTowns;
    List<String> ignoreGriefPrevetionPlayers;
    List<String> ignoreWorldGuardRegions;
    final JavaPlugin pl;
    private Runnable updateTask;

    public Main() {
        this.timer = new Timer((Plugin)this);
        this.zoneManager = new ZoneManager(this);
        this.cmdHandler = new CmdHandler(this);
        this.events = new Events(this);
        this.portalManager = new PortalManager(this);
        this.econ = null;
        this.updateMsg = null;
        this.oldConfigs = new String[0];
        this.townyHook = false;
        this.factionHook = false;
        this.worldBorderHook = false;
        this.worldBorderInstalled = false;
        this.griefPreventionHook = false;
        this.vaultHook = false;
        this.worldGuardHook = false;
        this.disabling = false;
        this.pl = this;
    }

    boolean useFactionHook() {
        return this.factionHook;
    }

    boolean useTownyHook() {
        return this.townyHook;
    }

    boolean useWorldBorderHook() {
        return this.worldBorderHook;
    }

    boolean isWorldBorderInstalled() {
        return this.worldBorderInstalled;
    }

    boolean useGriefPreventionHook() {
        return this.griefPreventionHook;
    }

    boolean useVaultHook() {
        return this.vaultHook;
    }

    boolean useWorldGuardHook() {
        return this.worldGuardHook;
    }

    boolean isDisabling() {
        return this.disabling;
    }

    public void checkForOldConfig() {
        final File f = new File(this.getDataFolder(), "config.yml");
        if (f.exists() && FileTools.read(f).replaceAll(" ", "").toLowerCase().contains("# Range.From:\n# this is from where the range is, can be \"spawn\", \"rlz\"(From the RandomLocationZone)".replaceAll(" ", "").toLowerCase())) {
            f.renameTo(new File(this.getDataFolder(), "oldConfig.yml"));
            this.getLogger().info("Found old config, renamed it to oldConfig.yml");
        }
    }

    @Deprecated
    public void configSave() {
        final HashMap<String, Object> values = new HashMap<String, Object>();
        for (final String s : this.getConfig().getDefaults().getKeys(true)) {
            values.put(s, this.getConfig().get(s));
        }
        for (final String s : this.getConfig().getKeys(true)) {
            values.put(s, this.getConfig().get(s));
        }
        final File f = new File(this.getDataFolder(), "config.yml");
        f.delete();
        InputStream is = null;
        OutputStream os = null;
        Label_0344: {
            try {
                is = this.getResource("config.yml");
                f.getParentFile().mkdirs();
                os = new FileOutputStream(f.getAbsolutePath());
                final byte[] buffer = new byte[1024];
                int bytesRead;
                while ((bytesRead = is.read(buffer)) != -1) {
                    os.write(buffer, 0, bytesRead);
                }
                is.close();
                os.flush();
                os.close();
            }
            catch (IOException e) {
                e.printStackTrace();
                if (is != null) {
                    try {
                        is.close();
                    }
                    catch (IOException e2) {
                        e2.printStackTrace();
                    }
                }
                if (os != null) {
                    try {
                        os.close();
                    }
                    catch (IOException e2) {
                        e2.printStackTrace();
                    }
                }
                break Label_0344;
            }
            finally {
                if (is != null) {
                    try {
                        is.close();
                    }
                    catch (IOException e2) {
                        e2.printStackTrace();
                    }
                }
                if (os != null) {
                    try {
                        os.close();
                    }
                    catch (IOException e2) {
                        e2.printStackTrace();
                    }
                }
            }
            if (is != null) {
                try {
                    is.close();
                }
                catch (IOException e2) {
                    e2.printStackTrace();
                }
            }
            if (os != null) {
                try {
                    os.close();
                }
                catch (IOException e2) {
                    e2.printStackTrace();
                }
            }
        }
        this.reloadConfig();
        for (final Map.Entry<String, Object> e3 : values.entrySet()) {
            this.getConfig().set((String)e3.getKey(), e3.getValue());
        }
        this.saveConfig();
    }

    public void saveDefaultConfigSafe() {
        this.saveDefaultConfig();
        this.reloadConfig();
        final FileConfiguration c = (FileConfiguration)YamlConfiguration.loadConfiguration(new File(this.getDataFolder(), "config.yml"));
        for (final String key : this.getDefaultConfig().getKeys(true)) {
            this.getLogger().info(String.valueOf(key) + ": " + this.getDefaultConfig().get(key));
            if (!c.contains(key)) {
                this.getConfig().set(key, this.getDefaultConfig().get(key));
            }
        }
        this.saveConfig();
    }

    public FileConfiguration getDefaultConfig() {
        if (this.defaultConfig == null) {
            this.defaultConfig = (FileConfiguration)YamlConfiguration.loadConfiguration((Reader)new InputStreamReader(this.getResource("config.yml")));
        }
        return this.defaultConfig;
    }

    public void onEnable() {
        System.out.println("=================   Enabling RandomLocation   ==================");
        this.checkForOldConfig();
        this.saveDefaultConfigSafe();
        Zone.setPlugin(this);
        this.checkHooks();
        this.timer.startTimer();
        System.out.println("================================================================");
        this.zoneManager.loadAll();
        this.zoneManager.startTask();
        this.zoneManager.backup.run();
        this.portalManager.startTask();
        this.checkForUpdate();
//        try {
//            final MetricsLite metrics = new MetricsLite((Plugin)this);
//            metrics.start();
//        }
//        catch (IOException ex) {}
        this.getServer().getPluginManager().registerEvents((Listener)this.events, (Plugin)this);
        System.out.println("================================================================");
    }

    private List<String> getLowerCaseList(final String path) {
        final List<String> list = (List<String>)this.getConfig().getStringList(path);
        for (int i = 0; i < list.size(); ++i) {
            list.set(i, list.get(i).toLowerCase());
        }
        return list;
    }

    public void checkHooks() {
        this.townyHook = false;
        this.factionHook = false;
        this.worldBorderHook = false;
        this.worldBorderInstalled = false;
        this.griefPreventionHook = false;
        this.vaultHook = false;
        this.worldGuardHook = false;
        try {
            if (this.getConfig().getBoolean("Hooks.UseFactionSupport")) {
                final Plugin p = this.getServer().getPluginManager().getPlugin("Factions");
                if (p != null) {
                    Class.forName("com.massivecraft.factions.Factions");
                    Class.forName("com.massivecraft.factions.entity.BoardColl");
                    Class.forName("com.massivecraft.factions.entity.Faction");
                    Class.forName("com.massivecraft.massivecore.ps.PS");
                }
                if (p instanceof Factions) {
                    this.factionHook = true;
                }
                else if (p != null) {
                    this.logPluginUncompatible("Factions");
                }
            }
        }
        catch (Exception e) {
            this.logPluginUncompatible("Factions");
        }
        this.ignoreFactions = this.getLowerCaseList("Hooks.IgnoreFactions");
        try {
            if (this.getConfig().getBoolean("Hooks.UseTownySupport")) {
                final Plugin p = this.getServer().getPluginManager().getPlugin("Towny");
                if (p != null) {
                    Class.forName("com.palmergames.bukkit.towny.Towny");
                    Class.forName("com.palmergames.bukkit.towny.object.WorldCoord");
                }
                if (p instanceof Towny) {
                    this.townyHook = true;
                }
                else if (p != null) {
                    this.logPluginUncompatible("Towny");
                }
            }
        }
        catch (Exception e) {
            this.logPluginUncompatible("Towny");
        }
        this.ignoreTowns = this.getLowerCaseList("Hooks.IgnoreTowns");
        try {
            final Plugin plugin = this.getServer().getPluginManager().getPlugin("WorldBorder");
            if (plugin != null) {
                Class.forName("com.wimbli.WorldBorder.WorldBorder");
                Class.forName("com.wimbli.WorldBorder.BorderData");
                Class.forName("com.wimbli.WorldBorder.Config");
            }
            final boolean hook = this.getConfig().getBoolean("Hooks.UseWorldBorderSupport");
            if (plugin instanceof WorldBorder) {
                this.worldBorderInstalled = true;
                if (hook) {
                    this.worldBorderHook = true;
                }
            }
            else if (plugin != null) {
                this.logPluginUncompatible("WorldBorder");
            }
        }
        catch (Exception e) {
            this.logPluginUncompatible("WorldBorder");
        }
        try {
            if (this.getConfig().getBoolean("Hooks.UseGriefPreventionSupport")) {
                final JavaPlugin p2 = (JavaPlugin)this.getServer().getPluginManager().getPlugin("GriefPrevention");
                if (p2 != null) {
                    Class.forName("me.ryanhamshire.GriefPrevention.GriefPrevention");
                }
                if (p2 instanceof GriefPrevention) {
                    this.griefPreventionHook = true;
                }
                else if (p2 != null) {
                    this.logPluginUncompatible("GriefPrevention");
                }
            }
        }
        catch (Exception e) {
            this.logPluginUncompatible("GriefPrevention");
        }
        this.ignoreGriefPrevetionPlayers = this.getLowerCaseList("Hooks.IgnoreGriefPrevetionPlayers");
        try {
            if (this.getConfig().getBoolean("Hooks.UseWorldGuardSupport")) {
                Plugin p = this.getServer().getPluginManager().getPlugin("WorldGuard");
                if (p != null) {
                    Class.forName("com.sk89q.worldguard.bukkit.WorldGuardPlugin");
                    Class.forName("com.sk89q.worldedit.Vector");
                    if (!Class.forName("com.sk89q.worldguard.protection.ApplicableRegionSet").isInterface()) {
                        this.logPluginUncompatible("WorldGuard");
                        p = null;
                    }
                }
                if (p instanceof WorldGuardPlugin) {
                    this.worldGuardHook = true;
                }
                else if (p != null) {
                    this.logPluginUncompatible("WorldGuard");
                }
            }
        }
        catch (Exception e) {
            this.logPluginUncompatible("WorldGuard");
        }
        this.ignoreWorldGuardRegions = this.getLowerCaseList("Hooks.IgnoreWorldGuardRegions");
        try {
            if (this.getConfig().getBoolean("Hooks.UseVaultSupport") && this.getServer().getPluginManager().getPlugin("Vault") != null) {
                Class.forName("net.milkbowl.vault.economy.Economy");
                final RegisteredServiceProvider<Economy> rsp = (RegisteredServiceProvider<Economy>)this.getServer().getServicesManager().getRegistration((Class)Economy.class);
                if (rsp != null) {
                    this.econ = (Economy)rsp.getProvider();
                    this.vaultHook = true;
                }
            }
        }
        catch (Exception e) {
            this.logPluginUncompatible("Vault");
        }
        this.getLogger().info("Hooking into Factions: " + this.factionHook);
        this.getLogger().info("Hooking into Towny: " + this.townyHook);
        this.getLogger().info("Hooking into WorldBorder: " + this.worldBorderHook);
        this.getLogger().info("Hooking into GriefPrevention: " + this.griefPreventionHook);
        this.getLogger().info("Hooking into Vault: " + this.vaultHook);
        this.getLogger().info("Hooking into WorldGuard: " + this.worldGuardHook);
    }

    void logPluginUncompatible(final String plName) {
        this.getLogger().warning("An unsupported version of " + plName + " was found!");
        this.getLogger().warning("Hook disabled!");
        this.getLogger().warning("If you are using the lates version of " + plName + " pleace report it");
        this.getLogger().warning("as I (the developer) might not be aware of the update");
        System.out.println("================================================================");
    }

    void checkForUpdate() {
        if (this.getConfig().getBoolean("AutoUpdater.Enable")) {
            Bukkit.getScheduler().runTaskAsynchronously((Plugin)this.pl, this.updateTask);
        }
    }

    private long convertStringToTicks(final String time) {
        long ticks = 0L;
        final String[] args = time.split(" ");
        String[] array;
        for (int length = (array = args).length, i = 0; i < length; ++i) {
            String arg = array[i];
            if (arg.contains("h")) {
                arg = arg.replaceAll("[a-zA-Z]", "");
                final long raw = Long.parseLong(arg);
                ticks += raw * 60L * 60L * 20L;
            }
            else if (arg.contains("m")) {
                arg = arg.replaceAll("[a-zA-Z]", "");
                final long raw = Long.parseLong(arg);
                ticks += raw * 60L * 20L;
            }
            else if (arg.contains("s")) {
                arg = arg.replaceAll("[a-zA-Z]", "");
                final long raw = Long.parseLong(arg);
                ticks += raw * 20L;
            }
        }
        return ticks;
    }

    public void onDisable() {
        this.disabling = true;
        Bukkit.getScheduler().cancelTasks((Plugin)this);
        this.zoneManager.backup.run();
    }

    public boolean onCommand(final CommandSender sender, final Command command, final String label, final String[] args) {
        this.cmdHandler.onCommand(sender, command, label, args);
        return false;
    }

    void reload() {
        System.out.println("=================   Reloading RandomLocation   =================");
        this.reloadConfig();
        this.checkHooks();
        this.zoneManager.backup.run();
        System.out.println("================================================================");
    }

    static /* synthetic */ File access$0(final Main main) {
        return main.getFile();
    }
}
